package link.chengguo.orangemall.service.ums.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.google.gson.Gson;
import link.chengguo.orangemall.ApiContext;
import link.chengguo.orangemall.component.OssAliyunUtil;
import link.chengguo.orangemall.component.UserUtils;
import link.chengguo.orangemall.enums.AllEnum;
import link.chengguo.orangemall.exception.ApiMallPlusException;
import link.chengguo.orangemall.exception.BusinessMallException;
import link.chengguo.orangemall.exception.MemberNotExitException;
import link.chengguo.orangemall.oms.mapper.OmsOrderMapper;
import link.chengguo.orangemall.oms.vo.OrderStstic;
import link.chengguo.orangemall.sys.mapper.SysAreaMapper;
import link.chengguo.orangemall.ums.entity.*;
import link.chengguo.orangemall.ums.mapper.SysAppletSetMapper;
import link.chengguo.orangemall.ums.mapper.UmsMemberMapper;
import link.chengguo.orangemall.ums.mapper.UmsMemberMemberTagRelationMapper;
import link.chengguo.orangemall.ums.service.*;
import link.chengguo.orangemall.util.*;
import link.chengguo.orangemall.utils.CommonResult;
import link.chengguo.orangemall.utils.MatrixToImageWriter;
import link.chengguo.orangemall.comment.SysConstant;
import link.chengguo.orangemall.utils.ValidatorUtils;
import link.chengguo.orangemall.vo.*;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.CompletableFuture;

/**
 * <p>
 * 会员表 服务实现类
 * </p>
 *
 * @author chengguo
 * @since 2019-04-19
 */
@Slf4j
@Service
public class UmsMemberServiceImpl extends ServiceImpl<UmsMemberMapper, UmsMember> implements IUmsMemberService {

    private static final Logger LOGGER = LoggerFactory.getLogger(UmsMemberServiceImpl.class);

    @Autowired
    OssAliyunUtil aliyunOSSUtil;
    Integer regJifen = 100;
    Integer logginJifen = 5;
    @Resource
    private SysAppletSetMapper appletSetMapper;
    @Resource
    private UmsMemberMapper memberMapper;
    @Resource
    private BCryptPasswordEncoder passwordEncoder;
    @Resource
    private RedisService redisService;
    /* @Resource
     private AuthenticationManager authenticationManager;*/
    @Resource
    private UserDetailsService userDetailsService;
    @Resource
    private SmsService smsService;
    @Resource
    private SysAreaMapper areaMapper;
    @Resource
    private JwtTokenUtil jwtTokenUtil;
    @Value("${redis.key.prefix.authCode}")
    private String REDIS_KEY_PREFIX_AUTH_CODE;
    @Value("${authCode.expire.seconds}")
    private Long AUTH_CODE_EXPIRE_SECONDS;
    @Value("${jwt.tokenHead}")
    private String tokenHead;
    @Value("${aliyun.sms.expire-minute:1}")
    private Integer expireMinute;
    @Value("${aliyun.sms.day-count:30}")
    private Integer dayCount;
    @Resource
    private UmsMemberMemberTagRelationMapper umsMemberMemberTagRelationMapper;
    @Resource
    private IUmsMemberLevelService memberLevelService;
    @Resource
    private OmsOrderMapper omsOrderMapper;
    @Resource
    private IUmsMemberBlanceLogService blanceLogService;
    @Resource
    private IUmsIntegrationChangeHistoryService umsIntegrationChangeHistoryService;
    @Autowired
    private ApiContext apiContext;
    private OkHttpClient okHttpClient = new OkHttpClient();

    @Override
    public UmsMember getNewCurrentMember() {
        UmsMember umsMember = null;
        try {
            umsMember = (UmsMember) this.getCurrentMember();
        } catch (Exception e) {

        }
        return umsMember;
    }

    @Override
    public Object webLogin(String wxH5Appid, String wxH5Secret, String code) {
        //H5 微信公众号网页登录
        try {
            log.info("https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                    + wxH5Appid + "&secret=" + wxH5Secret + "&code=" + code + "&grant_type=authorization_code");
            String json = okHttpClient.newCall(
                    new Request.Builder().url("https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                            + wxH5Appid + "&secret=" + wxH5Secret + "&code=" + code + "&grant_type=authorization_code").build()).execute().body().string();
            com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(json);
            log.info(jsonObject.toJSONString());
            Integer errcode = jsonObject.getInteger("errcode");
            if (errcode == null || errcode == 0) {
                String openid = jsonObject.getString("openid");
                Map<String, Object> resultObj = new HashMap<String, Object>();
                UmsMember userVo = this.queryByOpenId(openid);
                String token = null;
                if (null == userVo) {
                    UmsMember umsMember = new UmsMember();
                    umsMember.setUsername("wxapplet" + CharUtil.getRandomString(12));
                    umsMember.setSourceType(2);
                    umsMember.setPassword(passwordEncoder.encode("123456"));
                    umsMember.setCreateTime(new Date());
                    umsMember.setStatus(1);
                    umsMember.setBlance(new BigDecimal(10000));
                    umsMember.setIntegration(0);
                    umsMember.setMemberLevelId(4L);
                    umsMember.setWeixinOpenid(openid);
                    memberMapper.insert(umsMember);
                    token = jwtTokenUtil.generateToken(umsMember.getUsername());
                    resultObj.put("userId", umsMember.getId());
                    resultObj.put("userInfo", umsMember);
                    addIntegration(umsMember.getId(), regJifen, 1, "注册添加积分", AllEnum.ChangeSource.register.code(), umsMember.getUsername());

                } else {
                    addIntegration(userVo.getId(), logginJifen, 1, "登录添加积分", AllEnum.ChangeSource.login.code(), userVo.getUsername());

                    token = jwtTokenUtil.generateToken(userVo.getUsername());
                    resultObj.put("userId", userVo.getId());
                    resultObj.put("userInfo", userVo);
                }


                if (StringUtils.isEmpty(token)) {
                    throw new ApiMallPlusException("登录失败");

                }
                resultObj.put("tokenHead", tokenHead);
                resultObj.put("token", token);


                return new CommonResult().success(resultObj);
            } else {
                throw new ApiMallPlusException(jsonObject.toJSONString());
            }
        } catch (ApiMallPlusException e) {
            e.printStackTrace();
            throw new ApiMallPlusException(e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            throw new ApiMallPlusException(e.getMessage());
        }

    }

    @Override
    public String getWxPhone(String openid, String keyStr, String ivStr, String encDataStr) {
        //解析手机号
        WxPhoneInfo wxPhoneInfo = null;
        System.err.println("encDataStr=" + encDataStr + ",keyStr=" + keyStr + ",ivStr=" + ivStr);
        try {
            String result = AES.wxDecrypt(encDataStr, keyStr, ivStr);
            Gson gson = new Gson();
            wxPhoneInfo = gson.fromJson(result, WxPhoneInfo.class);
            if (wxPhoneInfo != null) {
                return wxPhoneInfo.getPhoneNumber();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public Object getCurrentMember() {
        try {
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
            String requestType = ((HttpServletRequest) request).getMethod();
            if ("OPTIONS".equals(requestType)) {
                return null;
            }
            UmsMember member = UserUtils.getCurrentMember();
            if (member != null && member.getId() != null) {
                return memberMapper.selectById(member.getId());
            }
            String storeId = request.getParameter("storeid");
            if (ValidatorUtils.empty(storeId)) {
                storeId = request.getHeader("storeid");
            }
            if (storeId == null) {
                storeId = "1";
            }
            String tokenPre = "authorization" + storeId;
            String authHeader = request.getParameter(tokenPre);
            if (ValidatorUtils.empty(authHeader)) {
                authHeader = request.getHeader(tokenPre);
            }
            if (authHeader != null && authHeader.startsWith("Bearer")) {
                String authToken = authHeader.substring("Bearer".length());
                String username = jwtTokenUtil.getUserNameFromToken(authToken);
                if (ValidatorUtils.notEmpty(username)) {
                    member = JsonUtils.jsonToPojo(redisService.get(apiContext.getCurrentProviderId() + ":" + String.format(Rediskey.MEMBER, username)), UmsMember.class);
                    if (member == null || member.getId() == null) {
                        member = getByUsername(username);
                    }
                    return member;
                }
            }
            return new CommonResult().fail(100);
        } catch (Exception e) {
            e.printStackTrace();
            return new UmsMember();
        }
    }

    @Override
    public void updataMemberOrderInfo() {
        List<OrderStstic> orders = omsOrderMapper.listOrderGroupByMemberId();
        List<UmsMemberLevel> levelList = memberLevelService.list(new QueryWrapper<UmsMemberLevel>().orderByDesc("price"));
        for (OrderStstic o : orders) {
            UmsMember member = new UmsMember();
            member.setId(o.getMemberId());
            member.setBuyMoney(o.getTotalPayAmount());
            for (UmsMemberLevel level : levelList) {
                if (member.getBuyMoney() != null) {
                    if (member.getBuyMoney().compareTo(level.getPrice()) >= 0) {
                        member.setMemberLevelId(level.getId());
                        member.setMemberLevelName(level.getName());
                        break;
                    }
                }
            }
            member.setBuyCount(o.getTotalCount());
            memberMapper.updateById(member);
        }
    }

    /**
     * 添加余额记录 并更新用户余额
     *
     * @param id
     * @param money
     */
    @Override
    public void addBlance(Long id, BigDecimal money, int type, String note) {
        UmsMemberBlanceLog blanceLog = new UmsMemberBlanceLog();
        blanceLog.setMemberId(id);
        blanceLog.setPrice(money);
        blanceLog.setCreateTime(new Date());
        blanceLog.setType(type);
        blanceLog.setNote(note);
        blanceLogService.save(blanceLog);
        UmsMember member = memberMapper.selectById(id);
        member.setBlance(member.getBlance().add(blanceLog.getPrice()));
        memberMapper.updateById(member);
    }

    /**
     * 添加积分记录 并更新用户积分
     *
     * @param id
     * @param integration
     */
    @Override
    public void addIntegration(Long id, Integer integration, int changeType, String note, int sourceType, String operateMan) {
       /* UmsIntegrationChangeHistory history = new UmsIntegrationChangeHistory();
        history.setMemberId(id);
        history.setChangeCount(integration);
        history.setCreateTime(new Date());
        history.setChangeType(changeType);
        history.setOperateNote(note);
        history.setSourceType(sourceType);
        history.setOperateMan(operateMan);
        umsIntegrationChangeHistoryService.save(history);
        UmsMember member = memberMapper.selectById(id);
        if (ValidatorUtils.empty(member.getIntegration())) {
            member.setIntegration(0);
        }
        member.setIntegration(member.getIntegration() + integration);
        memberMapper.updateById(member);
        redisService.set(apiContext.getCurrentProviderId() + ":" + String.format(Rediskey.MEMBER, member.getUsername()), JsonUtils.objectToJson(member));
    */
    }

    @Override
    public UmsMember getByUsername(String username) {
        UmsMember umsMember = new UmsMember();
        umsMember.setUsername(username);

        return memberMapper.selectOne(new QueryWrapper<>(umsMember));
    }

    @Override
    public UmsMember getById(Long id) {
        return memberMapper.selectById(id);
    }

    @Override
    public CommonResult register(String phone, String password, String confim, String authCode, String invitecode) {

        //没有该用户进行添加操作
        UmsMember umsMember = new UmsMember();
        umsMember.setUsername(phone);
        umsMember.setPhone(phone);
        umsMember.setSourceType(3);
        umsMember.setPassword(password);
        umsMember.setConfimpassword(confim);
        umsMember.setPhonecode(authCode);
        umsMember.setInvitecode(invitecode);
        if (ValidatorUtils.notEmpty(umsMember.getPhonecode()) && !verifyAuthCode(umsMember.getPhonecode(), umsMember.getPhone())) {
            return new CommonResult().failed("验证码错误");
        }
        return this.register(umsMember);
    }

    @Override
    public SmsCode generateCode(String phone) {
        //生成流水号
        String uuid = UUID.randomUUID().toString();
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        Map<String, String> map = new HashMap<>(2);
        map.put("code", sb.toString());
        map.put("phone", phone);

        //短信验证码缓存15分钟，
        redisService.set(REDIS_KEY_PREFIX_AUTH_CODE + phone, sb.toString());
        redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE + phone, expireMinute * 60);


        //存储sys_sms
        saveSmsAndSendCode(phone, sb.toString());
        SmsCode smsCode = new SmsCode();
        smsCode.setKey(uuid);
        return smsCode;
    }

    /**
     * 保存短信记录，并发送短信
     *
     * @param phone
     * @param code
     */
    private void saveSmsAndSendCode(String phone, String code) {
        checkTodaySendCount(phone);

        Sms sms = new Sms();
        sms.setPhone(phone);
        sms.setParams(code);
        Map<String, String> params = new HashMap<>();
        params.put("code", code);
        smsService.save(sms, JsonUtils.objectToJson(params));

        //异步调用阿里短信接口发送短信
        CompletableFuture.runAsync(() -> {
            try {
                smsService.sendSmsMsg(sms);
            } catch (Exception e) {
                params.put("err", e.getMessage());
                smsService.save(sms, JsonUtils.objectToJson(params));
                e.printStackTrace();
                LOGGER.error("发送短信失败：{}", e.getMessage());
            }

        });

        // 当天发送验证码次数+1
        String countKey = countKey(phone);
        redisService.increment(countKey, 1L);
        redisService.expire(countKey, 1 * 3600 * 24);
    }

    /**
     * 获取当天发送验证码次数
     * 限制号码当天次数
     *
     * @param phone
     * @return
     */
    private void checkTodaySendCount(String phone) {
        String value = redisService.get(countKey(phone));
        if (value != null) {
            Integer count = Integer.valueOf(value);
            if (count > dayCount) {
                throw new IllegalArgumentException("已超过当天最大次数");
            }
        }

    }

    private String countKey(String phone) {
        return "sms:count:" + LocalDate.now().toString() + ":" + phone;
    }

    @Override
    public UmsMember umsMemberIsExit(String userName) {
        UmsMember umsMember = new UmsMember();
        umsMember.setUsername(userName);
        UmsMember member = memberMapper.selectOne(new QueryWrapper<>(umsMember));
        if (member != null) {
            throw new MemberNotExitException("该用户已存在");
        }
        return null;
    }


    @Override
    public CommonResult register(UmsMember user) {
        //验证验证码
        if (ValidatorUtils.notEmpty(user.getPhonecode()) && !verifyAuthCode(user.getPhonecode(), user.getPhone())) {
            return new CommonResult().failed("验证码错误");
        }
        if (!user.getPassword().equals(user.getConfimpassword())) {
            return new CommonResult().failed("密码不一致");
        }
        //查询是否已有该用户

        //没有该用户进行添加操作
        try {
            umsMemberIsExit(user.getUsername());
        } catch (MemberNotExitException ex) {
            return new CommonResult().failed(ex.getMessage());
        }

        UmsMember umsMember = new UmsMember();
        umsMember.setMemberLevelId(SysConstant.UMS_MEMBER_DEFAULT_LEVEL);
        umsMember.setMemberLevelName(memberLevelService.getById(SysConstant.UMS_MEMBER_DEFAULT_LEVEL).getName());
        umsMember.setGroupId(SysConstant.UMS_MEMBER_DEFAULT_GROUP);
        umsMember.setUsername(user.getUsername());
        umsMember.setNickname(user.getNickname());
        umsMember.setSourceType(user.getSourceType());
        umsMember.setPhone(user.getPhone());
        umsMember.setPassword(passwordEncoder.encode(user.getPassword()));
        umsMember.setCreateTime(new Date());
        umsMember.setIcon(SysConstant.MEMBER_DEFAULT_ICON);
        //这是要生成二维码的url
        String url = "http://www.yjlive.cn:8082/?invitecode=" + user.getUsername();
        //要添加到二维码下面的文字
        String words = user.getUsername() + "的二维码";
        //调用刚才的工具类
        ByteArrayResource qrCode = MatrixToImageWriter.createQrCode(url, words);
        InputStream inputStream = new ByteArrayInputStream(qrCode.getByteArray());


        umsMember.setAvatar(aliyunOSSUtil.upload("png", inputStream));
        memberMapper.insert(umsMember);

        redisService.set(String.format(Rediskey.MEMBER, umsMember.getUsername()), JsonUtils.objectToJson(umsMember));

        addIntegration(umsMember.getId(), regJifen, 1, "注册添加积分", AllEnum.ChangeSource.register.code(), umsMember.getUsername());
        umsMember.setPassword(null);
        return new CommonResult().success("注册成功", null);
    }

    @Override
    public Object simpleReg(String username,String phone, String password, String confimpassword, String invitecode) {
        //没有该用户进行添加操作
        UmsMember user = new UmsMember();
        user.setUsername(username);
        user.setNickname(link.chengguo.orangemall.utils.StringUtils.ranString(SysConstant.UMS_MEMBER_NICK_SIZE));
        user.setPhone(phone);
        user.setPassword(password);
        user.setConfimpassword(confimpassword);
        user.setInvitecode(invitecode);
        return this.register(user);
    }

    @Override
    public CommonResult generateAuthCode(String telephone) {
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 6; i++) {
            sb.append(random.nextInt(10));
        }
        //验证码绑定手机号并存储到redis
        redisService.set(REDIS_KEY_PREFIX_AUTH_CODE + telephone, sb.toString());
        redisService.expire(REDIS_KEY_PREFIX_AUTH_CODE + telephone, AUTH_CODE_EXPIRE_SECONDS);
        return new CommonResult().success("获取验证码成功", sb.toString());
    }

    @Override
    public CommonResult updatePassword(String telephone, String password, String authCode) {
        UmsMember example = new UmsMember();
        example.setPhone(telephone);
        UmsMember member = memberMapper.selectOne(new QueryWrapper<>(example));
        if (member == null) {
            return new CommonResult().failed("该账号不存在");
        }
        //验证验证码
        if (!verifyAuthCode(authCode, telephone)) {
            return new CommonResult().failed("验证码错误");
        }

        member.setPassword(passwordEncoder.encode(password));
        memberMapper.updateById(member);
        redisService.set(String.format(Rediskey.MEMBER, member.getUsername()), JsonUtils.objectToJson(member));
        return new CommonResult().success("密码修改成功", null);
    }


    @Override
    public void updateIntegration(Long id, Integer integration) {
        UmsMember record = new UmsMember();
        record.setId(id);
        record.setIntegration(integration);
        memberMapper.updateById(record);
    }

    //对输入的验证码进行校验
    private boolean verifyAuthCode(String authCode, String telephone) {
        if (StringUtils.isEmpty(authCode)) {
            return false;
        }
        String realAuthCode = redisService.get(REDIS_KEY_PREFIX_AUTH_CODE + telephone);
        return authCode.equals(realAuthCode);
    }

    @Override
    public UmsMember queryByOpenId(String openId) {
        UmsMember queryO = new UmsMember();
        queryO.setWeixinOpenid(openId);
        return memberMapper.selectOne(new QueryWrapper<>(queryO));
    }

    @Override
    public Map<String, Object> appLogin(String openid, Integer sex, String headimgurl, String unionid, String nickname, String city, Integer source) {
        Map<String, Object> resultObj = new HashMap<String, Object>();
        UmsMember userVo = this.queryByOpenId(openid);
        String token = null;
        if (null == userVo) {
            UmsMember umsMember = new UmsMember();
            umsMember.setUsername("wxapplet" + CharUtil.getRandomString(12));
            umsMember.setSourceType(source);
            umsMember.setPassword(passwordEncoder.encode("123456"));
            umsMember.setCreateTime(new Date());
            umsMember.setCity(city);
            umsMember.setAvatar(headimgurl);
            umsMember.setGender(sex);
            umsMember.setHistoryIntegration(0);
            umsMember.setWeixinOpenid(openid);
            if (StringUtils.isEmpty(headimgurl)) {
                //会员头像(默认头像)
                umsMember.setIcon(SysConstant.MEMBER_DEFAULT_ICON);
            } else {
                umsMember.setIcon(headimgurl);
            }

            umsMember.setNickname(nickname);
            umsMember.setPersonalizedSignature(unionid);
            memberMapper.insert(umsMember);
            token = jwtTokenUtil.generateToken(umsMember.getUsername());
            resultObj.put("userId", umsMember.getId());
            resultObj.put("userInfo", umsMember);
            addIntegration(umsMember.getId(), logginJifen, 1, "登录添加积分", AllEnum.ChangeSource.login.code(), umsMember.getUsername());

        } else {
            addIntegration(userVo.getId(), regJifen, 1, "注册添加积分", AllEnum.ChangeSource.register.code(), userVo.getUsername());

            token = jwtTokenUtil.generateToken(userVo.getUsername());
            resultObj.put("userId", userVo.getId());
            resultObj.put("userInfo", userVo);
        }
        if (StringUtils.isEmpty(token)) {
            throw new ApiMallPlusException("登录失败");
        }
        resultObj.put("tokenHead", tokenHead);
        resultObj.put("token", token);
        return resultObj;
    }

    @Override
    public Object getAppletOpenId(AppletLoginParam req) {
        SysAppletSet appletSet = appletSetMapper.selectOne(new QueryWrapper<>());
        if (null == appletSet) {
            throw new ApiMallPlusException("没有设置支付配置");
        }
        String openIdUrl  = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";
        String code = req.getCode();
        if (StringUtils.isEmpty(code)) {
            log.error("code ie empty");
            throw new ApiMallPlusException("code ie empty");
        }
        //获取openid
        String requestUrl = String.format(openIdUrl,
                appletSet.getAppid(),
                appletSet.getAppsecret(),
                code);

        System.out.println(requestUrl);
        JSONObject sessionData = CommonUtil.httpsRequest(requestUrl, "GET", null);
        return new CommonResult().success(sessionData);
    }

    @Override
    public Object wxappLogin(AppletLoginParam loginParam){
        Map<String, Object> tokenMap = new HashMap<>();
        Map<String,Object> me = JsonUtils.readJsonToMap(loginParam.getUserInfo());
        if(ValidatorUtils.isEmpty(me)||ValidatorUtils.isEmpty(loginParam.getOpenid())){
            throw new ApiMallPlusException("登录失败:微信用户信息获取失败");
        }
        //根据openid查询用户信息，没有就创建
        UmsMember umsMember = memberMapper.selectOne(new QueryWrapper<UmsMember>().eq("weixin_openid", loginParam.getOpenid()));
        if(ValidatorUtils.isEmpty(umsMember)){
            UmsMember umsMember1 = new UmsMember();
            umsMember1.setUsername(loginParam.getOpenid());
            umsMember1.setNickname(me.get("nickName").toString());
            umsMember1.setCreateTime(new Date());
            umsMember1.setIcon(me.get("avatarUrl").toString());
            if(ValidatorUtils.isEmpty(umsMember1.getIcon())){
                umsMember1.setIcon(SysConstant.MEMBER_DEFAULT_ICON);
            }
            umsMember1.setGender((Integer) me.get("gender"));
            umsMember1.setCity(me.get("country").toString() + "-" + me.get("province").toString() + "-" + me.get("city").toString());
            umsMember1.setSourceType(2);
            umsMember1.setWeixinOpenid(loginParam.getOpenid());
            umsMember1.setMemberLevelName(memberLevelService.getById(SysConstant.UMS_MEMBER_DEFAULT_LEVEL).getName());
            memberMapper.insert(umsMember1);
            umsMember = umsMember1;
        }
        MemberDetails userDetails = (MemberDetails) userDetailsService.loadUserByUsername(umsMember.getUsername());
        String token = getTokenByName(userDetails);
        if(ValidatorUtils.isEmpty(token)){
            throw new ApiMallPlusException("登录失败");
        }
        tokenMap.put("userInfo", userDetails);
        tokenMap.put("tokenHead", tokenHead);
        tokenMap.put("token", token);
        return tokenMap;

    }

    @Override
    public Object loginByWeixin(AppletLoginParam req) {
            String userInfos = req.getUserInfo();
            log.info(userInfos);
            Map<String, Object> me = JsonUtils.readJsonToMap(userInfos);
            if (null == me) {
                throw new ApiMallPlusException("登录失败 userInfos is null");
            }
            Map<String, Object> resultObj = new HashMap<String, Object>();
            UmsMember userVo = null;
            //根据openid查询用户信息
            if (ValidatorUtils.notEmpty(req.getOpenid())) {
                UmsMember queryO = new UmsMember();
                queryO.setWeixinOpenid(req.getOpenid());
                userVo = memberMapper.selectOne(new QueryWrapper<>(queryO));
                // 判断是否绑定了手机号
                if (userVo == null && req.getPhone() == null) {
                    throw new BusinessMallException("手机号为空，请先绑定手机号");
                }
            } else {
                throw new ApiMallPlusException("登录失败 openid不能为空");
            }

            String token = null;
            if (null == userVo) {
                //查询该手机号是否存在
                UmsMember queryO = new UmsMember();
                queryO.setPhone(req.getPhone());
                UmsMember umsMember = memberMapper.selectOne(new QueryWrapper<>(queryO));
                if (umsMember == null) {
                    umsMember = new UmsMember();
//                    umsMember.setUsername("wxapplet" + CharUtil.getRandomString(8));
                    umsMember.setUsername(req.getPhone());
                    umsMember.setPassword(passwordEncoder.encode("123456"));
                }
//                UmsMember umsMember = new UmsMember();
                umsMember.setSourceType(2);
                umsMember.setCreateTime(new Date());
                umsMember.setPhone(req.getPhone());
                umsMember.setAvatar(req.getCloudID());
                umsMember.setCity(me.get("country").toString() + "-" + me.get("province").toString() + "-" + me.get("city").toString());

                umsMember.setGender((Integer) me.get("gender"));
                umsMember.setWeixinOpenid(req.getOpenid());
                if (StringUtils.isEmpty(me.get("avatarUrl").toString())) {
                    //会员头像(默认头像)
                    umsMember.setIcon("http://orangemall.oss-cn-shanghai.aliyuncs.com/orangemall20200724/用户头像.png");
                } else {
                    umsMember.setIcon(me.get("avatarUrl").toString());
                }
                // umsMember.setGender(Integer.parseInt(me.get("gender")));
                umsMember.setNickname(me.get("nickName").toString());
                if (umsMember.getId() != null) {
                    memberMapper.updateById(umsMember);
                } else {
                    memberMapper.insert(umsMember);
                }
                MemberDetails userDetails = (MemberDetails) userDetailsService.loadUserByUsername(umsMember.getUsername());
                Authentication authentication = new UsernamePasswordAuthenticationToken(
                        userDetails, null, userDetails.getAuthorities());
                SecurityContextHolder.getContext().setAuthentication(authentication);
                token = jwtTokenUtil.generateToken(userDetails);
                resultObj.put("userId", umsMember.getId());
                resultObj.put("userInfo", umsMember);
                redisService.set(String.format(Rediskey.ACCESS_TOKEN_KEY, userDetails.getUsername()), JsonUtils.objectToJson(token));
                addIntegration(umsMember.getId(), logginJifen, 1, "登录添加积分", AllEnum.ChangeSource.login.code(), umsMember.getUsername());

            } else {
                //  userVo = this.queryByOpenId(sessionData.getString("openid"));
                if (ValidatorUtils.notEmpty(userVo.getWeixinOpenid())) {
                    addIntegration(userVo.getId(), regJifen, 1, "注册添加积分", AllEnum.ChangeSource.register.code(), userVo.getUsername());
                    MemberDetails userDetails = (MemberDetails) userDetailsService.loadUserByUsername(userVo.getUsername());
                    Authentication authentication = new UsernamePasswordAuthenticationToken(
                            userDetails, null, userDetails.getAuthorities());
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    token = jwtTokenUtil.generateToken(userDetails);
                    resultObj.put("userId", userVo.getId());
                    resultObj.put("userInfo", userVo);
                } else {
                    userVo.setPassword(passwordEncoder.encode("123456"));
                    userVo.setCreateTime(new Date());
                    userVo.setAvatar(req.getCloudID());
                    userVo.setCity(me.get("country").toString() + "-" + me.get("province").toString() + "-" + me.get("city").toString());
                    if (req.getPhone() != null) {
                        userVo.setPhone(req.getPhone());
                    }
                    userVo.setGender((Integer) me.get("gender"));
                    userVo.setWeixinOpenid(req.getOpenid());
                    if (StringUtils.isEmpty(me.get("avatarUrl").toString())) {
                        //会员头像(默认头像)
                        userVo.setIcon("http://orangemall.oss-cn-shanghai.aliyuncs.com/orangemall20200724/用户头像.png");
                    } else {
                        userVo.setIcon(me.get("avatarUrl").toString());
                    }
                    // umsMember.setGender(Integer.parseInt(me.get("gender")));
                    userVo.setNickname(me.get("nickName").toString());

                    memberMapper.updateById(userVo);
                }

            }
            if (StringUtils.isEmpty(token)) {
                throw new ApiMallPlusException("登录失败");
            }
            resultObj.put("tokenHead", tokenHead);
            resultObj.put("token", token);
            return new CommonResult().success(resultObj);

    }

    @Override
    public String refreshToken(String oldToken) {
        String token = oldToken.substring(tokenHead.length());
        if (jwtTokenUtil.canRefresh(token)) {
            return jwtTokenUtil.refreshToken(token);
        }
        return null;
    }


    @Override
    public Map<String, Object> loginByCode(String phone, String authCode) {
        Map<String, Object> tokenMap = new HashMap<>();
        String token = "";
        try {
            UserDetails userDetails = userDetailsService.loadUserByUsername(phone);

            UmsMember member = this.getByUsername(phone);

            //用户存在
            if (member != null) {
                //验证验证码
                if (!verifyAuthCode(authCode, member.getPhone())) {
                    throw new ApiMallPlusException("验证码错误");
                }
            } else {
                throw new ApiMallPlusException("用户不存在，请先去注册");

            }

            token = getTokenByName(userDetails);
            tokenMap.put("userInfo", member);
            addIntegration(member.getId(), logginJifen, 1, "登录添加积分", AllEnum.ChangeSource.login.code(), member.getUsername());

        } catch (AuthenticationException e) {
            LOGGER.warn("登录异常:{}", e.getMessage());

        }
        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);

        return tokenMap;
    }

    @Override
    public Map<String, Object> login(String username, String password) {

        Map<String, Object> tokenMap = new HashMap<>();
        String token = null;
        try {
            UmsMember member = this.getByUsername(username);
            member.setLoginTime(new Date());
            this.updateById(member);
            MemberDetails userDetails = (MemberDetails) userDetailsService.loadUserByUsername(username);
            if (!passwordEncoder.matches(password, userDetails.getPassword())) {
                throw new BadCredentialsException("密码不正确");
            }

            //验证验证码
           /* if (!verifyAuthCode(user.getCode(), member.getPhone())) {
                throw  new ApiMallPlusException("验证码错误");
            }*/

            //   Authentication authentication = authenticationManager.authenticate(authenticationToken);
            addIntegration(member.getId(), logginJifen, 1, "登录添加积分", AllEnum.ChangeSource.login.code(), member.getUsername());
            token = getTokenByName(userDetails);
            tokenMap.put("userInfo", member);
        } catch (Exception e) {
            LOGGER.warn("登录异常:{}", e.getMessage());

        }

        tokenMap.put("token", token);
        tokenMap.put("tokenHead", tokenHead);

        return tokenMap;

    }
    private String getTokenByName(UserDetails userDetails){
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        String token = jwtTokenUtil.generateToken(userDetails);
        redisService.set(String.format(Rediskey.ACCESS_TOKEN_KEY, userDetails.getUsername()), JsonUtils.objectToJson(token));
        return token;
    }
    @Override
    public Object initMemberRedis() {
        List<UmsMember> list = memberMapper.selectList(new QueryWrapper<>());
        for (UmsMember member : list) {
            redisService.set(String.format(Rediskey.MEMBER, member.getUsername()), JsonUtils.objectToJson(member));
        }
        return 1;
    }

    @Override
    public Object refreshMember() {
        UmsMember member = memberMapper.selectById(UserUtils.getCurrentMember().getId());
        redisService.set(String.format(Rediskey.MEMBER, member.getUsername()), JsonUtils.objectToJson(member));

        return 1;
    }

}

